package cz.hanis.android.geography;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.actionbarsherlock.app.SherlockActivity;

import cz.hanis.android.geography.activities.TestResultActivity;


public abstract class TimeTestActivity extends SherlockActivity {

	public static final String TAG_TEST_PROGRESS_THREAD = "TIME TEST PROGRESS THREAD";
	public static final String TAG = "TimeTestActivity";
	protected static final int ANSWERE_TIMED_OUT = -1;
	protected static final int ANSWERE_CORRECT = -3;
	protected static final int ANSWERE_INCORRECT = -4;
	protected static final int ANSWERE_NONE = -2;

	private int progressStatus;
	private Thread progressThread;
	private int time = 60;
	private boolean answering = false;

	private TestSpecification test;
	private int correct;
	private int incorrect;
	private int highscore;

	private TextView tvQuestion;
	private ProgressBar pbProgressBar;

	private TextView tvCorrect;
	private TextView tvIncorrect;
	private TextView tvHighscore;
	
	private TextView tvTimeLeft;

	private CountryTools tools;

	private List<View> answerViews;
	private View questionView;

	private Animation incorrectAnimation;
	private Animation correctAnimation;


	private Handler progressHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			progressStatus++;
			if (progressStatus > time) {
				finish();
			} else {
				pbProgressBar.setProgress(progressStatus);
				tvTimeLeft.setText(String.valueOf(time - progressStatus));
				
			}

		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.time_test_layout);

		incorrectAnimation = AnimationUtils.loadAnimation(this,
				R.anim.incorrect_flag);
		incorrectAnimation.setRepeatCount(6);
		correctAnimation = AnimationUtils.loadAnimation(this,
				R.anim.correct_flag);

		tools = GeographyApplication.getInstance().getCountryTool();
		answerViews = new ArrayList<View>();
		test = (TestSpecification) getIntent().getParcelableExtra(
				TestSpecification.KEY);

		tvHighscore = (TextView) findViewById(R.id.tv_time_test_status_highscore);
		tvCorrect = (TextView) findViewById(R.id.tv_time_test_status_correct);
		tvIncorrect = (TextView) findViewById(R.id.tv_time_test_status_incorrect);
		tvTimeLeft = (TextView) findViewById(R.id.tv_time_test_time_left);

		pbProgressBar = (ProgressBar) findViewById(R.id.pb_time_test_progress);
		pbProgressBar.setMax(time);
		tvQuestion = (TextView) findViewById(R.id.tv_time_test_question);
		init();
	}

	protected void setQuestionView(View questionView) {
		this.questionView = questionView;
	}

	protected View getQuestionView() {
		return questionView;
	}

	protected CountryTools getTools() {
		return tools;
	}

	private void init() {
		correct = 0;
		incorrect = 0;
		int highscore = GeographyApplication.getInstance().getHighScoreHandler().getHighScore(test);
		tvHighscore.setText(String.valueOf(highscore));
		tvCorrect.setText(String.valueOf(correct));
		tvIncorrect.setText(String.valueOf(incorrect));
		tvTimeLeft.setText(String.valueOf(time));
		startCounting();
	}

	private void onCorrect() {
		questionView.startAnimation(correctAnimation);
		correct++;
		tvCorrect.setText(String.valueOf(correct));
	}

	private void onIncorrect() {
		questionView.startAnimation(incorrectAnimation);
		incorrect++;
		tvIncorrect.setText(String.valueOf(incorrect));
	}

	protected void setQuestion(String question) {
		tvQuestion.setText(question);
	}

	protected void setTestLayout(int layout) {
		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View child = inflater.inflate(layout, null);
		LinearLayout root = (LinearLayout) findViewById(R.id.ll_time_test);
		root.addView(child);
	}

	public void newRound() {		
		enableAnswerViews();
		onNewRound();
		//startCounting();
		answering = true;
		// }
	}

	public void finish() {
		removeCallbacks();
		Intent intent = new Intent(TimeTestActivity.this, TestResultActivity.class);
		intent.putExtra(TestSpecification.KEY, test);
		intent.putExtra(TestResultActivity.CORRECT_ANSWER_KEY, correct);
		intent.putExtra(TestResultActivity.INCORRECT_ANSWER_KEY, incorrect);
		startActivity(intent);
		super.finish();
	}
	
	private void removeCallbacks() {
		if(progressThread != null && progressHandler != null) {
			progressHandler.removeCallbacks(progressThread);
		}				
	}

	private void startCounting() {
		removeCallbacks();
		progressThread = new Thread(new Runnable() {
			@Override
			public void run() {
				while (progressStatus <= time) {
					Log.d(TAG, "progressStatus: " + progressStatus);
					try {
						progressHandler.sendMessage(progressHandler
								.obtainMessage());
						Thread.sleep(1000);
					} catch (Throwable t) {
						t.printStackTrace();
						Log.d(TestActivity.TAG_TEST_PROGRESS_THREAD,
								t.getMessage());
					}
				}
			}
		});
		progressThread.start();
	}

	protected void answer(int answer) {
		answering = false;
		disableAnswerViews();
		int answerType = onAnswer(answer);
		removeCallbacks();
		if (answerType == ANSWERE_CORRECT) {
			onCorrect();
		} else {
			onIncorrect();
		}

			//pbProgressBar.setVisibility(View.INVISIBLE);
			Handler handler = new Handler();
			handler.postDelayed(new Runnable() {
				public void run() {
					newRound();
				}
			}, 500);
		
	}

	protected void answer() {
		answer(TestActivity.ANSWERE_NONE);
	}

	protected abstract void onNewRound();

	protected abstract int onAnswer(int answer);

	public boolean isAnswering() {
		return answering;
	}

	public void setAnswering(boolean answering) {
		this.answering = answering;
	}

	public TestSpecification getTest() {
		return test;
	}

	public void setTest(TestSpecification test) {
		this.test = test;
	}

	protected void enableAnswerViews() {
		for (View view : answerViews) {
			view.setEnabled(true);
		}
	}

	protected void disableAnswerViews() {
		for (View view : answerViews) {
			view.setEnabled(false);
		}
	}

	public List<View> getAnswerViews() {
		return answerViews;
	}

	public void addAnswerView(View view) {
		answerViews.add(view);
	}

	public int getNumberOfAnswers() {
		return answerViews.size();
	}

}
